#include "TerminalPlugin.h"

#include <QMainWindow>
#include <QTabBar>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>

#include "Terminal.h"
#include "QTerminalWidget.h"

TerminalPlugin::TerminalPlugin(QWidget* notepad, QMenu* menu, const QString& pluginModulePath, QObject *parent)
	: QObject(parent), m_notepadWidget(notepad), m_menu(menu), m_pluginModulePath(pluginModulePath),
	m_dockWidget(nullptr), m_dockTitleBarWidget(nullptr), m_dockEmptyTitleBarWidget(new QWidget()), 
	m_tabWidget(nullptr)
{
	if (!loadConfig(m_pluginModulePath, m_terminalList))
		return;

	for (auto it = m_terminalList.begin(); it != m_terminalList.end(); ++it) {

		qDebug() << (*it)->name() << (*it)->command() << (*it)->shortcut();
		
		auto action = m_menu->addAction((*it)->name());
		action->setShortcut(QKeySequence((*it)->shortcut()));
		action->setData(QVariant::fromValue(*it));

		connect(action, SIGNAL(triggered()), this, SLOT(onMenuItemClick()));
	}
}

#include <qsciscintilla.h>
extern std::function<QsciScintilla* (QWidget*)> getCurrentEditor;

void TerminalPlugin::onMenuItemClick()
{
	auto action = qobject_cast<QAction*>(sender());

	auto terminal = action->data().value<Terminal*>();

	//qDebug() << terminal->name() << terminal->command();

	auto mainWindow = dynamic_cast<QMainWindow*>(m_notepadWidget);
	if (!mainWindow)
		return;

	if (!m_dockWidget) {
		m_dockWidget = new QDockWidget(mainWindow);
		m_dockTitleBarWidget = m_dockWidget->titleBarWidget();
		m_dockWidget->setTitleBarWidget(m_dockEmptyTitleBarWidget);
		m_dockWidget->setMinimumSize(100, 200);
		connect(m_dockWidget, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(onDockLocationChanged(Qt::DockWidgetArea)));
		mainWindow->addDockWidget(Qt::BottomDockWidgetArea, m_dockWidget);
	}

	if (!m_dockWidget->isVisible())
		m_dockWidget->show();

	if (!m_tabWidget) {
		m_tabWidget = new QTabWidget(m_dockWidget);
		m_tabWidget->setTabsClosable(true);
		m_tabWidget->setMovable(true);
		m_tabWidget->tabBar()->setStyleSheet("QTabBar::tab{padding-left:10px}");
		connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequested(int)));
		m_dockWidget->setWidget(m_tabWidget);
	}

	QString currentDir = "";

	auto currentEditor = getCurrentEditor(m_notepadWidget);
	if (currentEditor) {
		auto filePath = currentEditor->property("filePath").toString();
		QFileInfo fileInfo(filePath);
		if (fileInfo.exists()) {
			currentDir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath());
		}
	}

	int tabIndex = m_tabWidget->addTab(new QTerminalWidget(terminal->command(), currentDir), terminal->name());
	m_tabWidget->setCurrentIndex(tabIndex);
}

void TerminalPlugin::onDockLocationChanged(Qt::DockWidgetArea area)
{
	if (area == Qt::NoDockWidgetArea) {
		m_dockWidget->setTitleBarWidget(m_dockTitleBarWidget);
	}
	else {
		m_dockWidget->setTitleBarWidget(m_dockEmptyTitleBarWidget);
	}
}

void TerminalPlugin::onTabCloseRequested(int index)
{
	auto widget = m_tabWidget->widget(index);
	if (widget)
		delete widget;

	if (m_tabWidget->count() == 0)
		m_dockWidget->hide();
}

bool TerminalPlugin::loadConfig(const QString& pluginFilePath, QList<Terminal*>& terminals)
{
	QString pluginPath = GetPluginDir(pluginFilePath);

	QString confFilePath = QString("%1/%2").arg(pluginPath).arg("ndd-terminal-plugin.json");

	QFile file(confFilePath);
	if (!file.exists()) {
		qDebug() << "conf.json not found.";
		return false;
	}

	if (!file.open(QIODevice::ReadOnly)) {
		qDebug() << "open conf.json failed.";
		return false;
	}

	QJsonParseError error;
	auto jsonDoc = QJsonDocument::fromJson(file.readAll(), &error);
	if (error.error != QJsonParseError::NoError) {
		qDebug() << "parse conf.json failed.";
		return false;
	}

	auto root = jsonDoc.object();

	if (root.contains("terminals")) {

		auto terminalsArr = root["terminals"].toArray();

		foreach(auto terminalObj, terminalsArr) {

			//qDebug() << terminalObj;

			if (terminalObj["name"].isUndefined() || !terminalObj["name"].isString())
				continue;

			if (terminalObj["command"].isUndefined() || !terminalObj["command"].isString())
				continue;

			QString shortcut = "";
			if (!terminalObj["shortcut"].isUndefined() && terminalObj["shortcut"].isString())
				shortcut = terminalObj["shortcut"].toString();

			auto name = terminalObj["name"].toString();
			auto command = terminalObj["command"].toString();

			terminals.append(new Terminal(name, command, shortcut));
		}
	}

	return true;
}

QString TerminalPlugin::GetPluginDir(const QString& pluginModulePath)
{
	QString filePath = QDir::fromNativeSeparators(pluginModulePath);

	return filePath.left(filePath.lastIndexOf("/") + 1);
}

TerminalPlugin::~TerminalPlugin()
{
}


